#include "NewtonInterp.h"
#include "InterConditions.h"
#include "Polynomial.h"
#include<vector>
using namespace std;

int main()
{
  
  //testing the class Polynomial
  cout<<"testing the class Polynomial!"<<endl;
  vector<double> arr(3,1);
  Polynomial p1(2,arr);
  cout<<"polynomial p1: "<<p1<<endl;
  Polynomial p2(2,arr);
  cout<<"polynomial p2: "<<p2<<endl;
  cout<<"the derivative of p1: "<<p1.get_deri()<<endl;
  cout<<"the value of p1 at x=2: "<<p1.get_value(2)<<endl;
  cout<<"the value of p1' at x=1: "<<p1.get_deri_value(1)<<endl;
  cout<<"p1+p2: "<<p1+p2<<endl;
  cout<<"p1-p2: "<<p1-p2<<endl;
  cout<<"p1*p2: "<<p1*p2<<endl;
  cout<<"***************************";
  
  cout<<endl;
  cout<<endl;

  
  //testing the class InterConditions
  cout<<"testing the class InterConditions!"<<endl;
  int n=3;
  vector<double> _X = {0,1,3};
  vector<double> _f = {1,2,0};
  vector<double> _m = {0,1,1};
  vector<vector<double> > _df(n,vector<double>(1));
  _df[0][0]=0; _df[1][0]=-1; _df[2][0]=0;
  InterConditions Q(n,_X,_f,_m,_df);
  cout<<"the divided difference table of datas you input(exercise 6 in the homework!):"<<endl;
  vector<double> X_=Q.get_X();
  vector<vector<double> > arry=Q.output_difftable();
  for(int i=0;i<arry.size();i++)
    {
      cout<<X_[i]<<" ";
    for(int j=0;j<=i;j++)
	cout<<arry[i][j]<<" ";
    cout<<endl;
    }
  cout<<"***************************";
  
  cout<<endl;
  cout<<endl;

  
  //testing the class NewtonInterp
  
  cout<<"testing the class NewtonInterp!"<<endl;
  cout<<"testing Method One!"<<endl;
  NewtonInterp P(Q);
  P.Interpolation_Method1();
  Polynomial P3=P.get_interPoly_();
  cout<<"the interpolation polynomial of datas you input: "<<endl;
  cout<<P3<<endl;
  cout<<"the value of the interpolation polynomial at x=2: "<<P3.get_value(2)<<endl;
  cout<<"***************************";
  //testing Method Two
  cout<<"\n"<<"testing Method Two!"<<endl;
  vector<double> _X1 = {0,1};
  vector<double> _f1 = {1,2};
  vector<double> _m1 = {0,1};
  vector<vector<double> > _df1(2,vector<double>(1));
  _df1[0][0]=0;
  _df1[1][0]=-1;
  InterConditions Q1(2,_X1,_f1,_m1,_df1);
  NewtonInterp P1(Q1);
  P1.Interpolation_Method1();
  cout<<"the interpolation polynomial of current datas:"<<endl;
  cout<<P1.get_interPoly_()<<endl;
  vector<double> New_X = {3};
  vector<double> New_f = {0};
  vector<double> New_m = {1};
  vector<vector<double> > New_df(1,vector<double>(1));
  New_df[0][0]=0;
  P1.Interpolation_Method2(New_X,New_f,New_m,New_df);
  cout<<"new interpolation polynomial after you newly add datas:"<<endl;
  cout<<P1.get_interPoly_()<<endl;
  
  
  cout<<"***************************";
  cout<<endl;
  //testing static Neville-Aitken algorithm,namely example 3.30 in notes
  cout<<"testing static Neville-Aitken algorithm,namely example 3.30 in notes!"<<endl;
  vector<double> _X_ = {0,1,2,3};
  vector<double> _f_ = {6,-3,-6,9};
  InterConditions QQ(4,_X_,_f_);
  cout<<"its value at x=1.5 by Neville-Aitken algorithm: "<<NewtonInterp::Neville_Aitken(QQ,1.5)<<endl;
  cout<<"\n"<<endl;
  cout<<"more details are shown in 'test report.pdf'!"<<endl;
  return 0;
}
